package cn.itcast.service.cargo;


import cn.itcast.dao.cargo.*;
import cn.itcast.domain.cargo.*;
import cn.itcast.vo.ExportProductResult;
import cn.itcast.vo.ExportResult;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

@Service(timeout = 100000)
public class ExportServiceImpl implements ExportService{

    // 注入报运单信息
    @Autowired
    private ExportDao exportDao;
    @Autowired
    private ExportProductDao exportProductDao;
    @Autowired
    private ExtEproductDao extEproductDao;

    // 注入购销合同信息
    @Autowired
    private ContractDao contractDao;
    @Autowired
    private ContractProductDao contractProductDao;
    @Autowired
    private ExtCproductDao extCproductDao;

    @Override
    public Export findById(String id) {
        Export export = exportDao.selectByPrimaryKey(id);
        return export;
    }


    /**
     * 对象拷贝：
     *    org.apache.commons.beanutils.BeanUtils.copyProperties(目标对象,数据源);
     *    org.springframework.beans.BeanUtils.copyProperties(数据源,目标对象)
     */
    @Override
    public void save(Export export) {
        //1.设置报运单id、商品种类数量、附件种类数量、装填
        export.setId(UUID.randomUUID().toString());
        export.setState(0);

        String contractIds = export.getContractIds();
        String[] strings = contractIds.split(",");
        //数组才可以转换成集合，这是购销合同id集合
        List<String> contractIdsList = Arrays.asList(strings);

        //2. 根据购销合同id，获取合同号；修改购销合同状态为2表示已经生成报运


        //2.1根据合同id集合，找出响应的合同
        ContractExample contractExample = new ContractExample();
        ContractExample.Criteria criteria = contractExample.createCriteria();
        criteria.andIdIn(contractIdsList);
        List<Contract> contracts = contractDao.selectByExample(contractExample);
        //集合判断
        if(contracts == null && contracts.size() == 0){
            throw  new RuntimeException("购销合同id为空");
        }

        //2.2遍历合同集合，获得合同号
        //遍历集合，想要获取里面对象的属性，可以使用字符串或者数组来接受
        String contractNos="";
        for (Contract contract : contracts) {
            contractNos = contract.getContractNo()+" ";
            //点击报运按钮以后，那么合同就不能再重新报运，所以将状态设置为2
            contract.setState(2);
            contractDao.updateByPrimaryKeySelective(contract);
        }

        Map<String,String> idMap =  new HashMap<>();

        //3. 根据购销合同id查询所有货物，再把货物数据录入到商品表
        ContractProductExample cpExample = new ContractProductExample();
        cpExample.createCriteria().andContractIdIn(contractIdsList);
        List<ContractProduct> contractProductList = contractProductDao.selectByExample(cpExample);
        if(contractProductList!=null && contractProductList.size()>0){
            for (ContractProduct contractProduct : contractProductList) {
                //创建商品对象
                ExportProduct exportProduct = new ExportProduct();
                BeanUtils.copyProperties(contractProduct,exportProduct);
                //设置商品id
                exportProduct.setId(UUID.randomUUID().toString());
                //商品表存有报运单id，设置报运单id
                exportProduct.setExportId(export.getId());
                //【保存商品对象】
                exportProductDao.insertSelective(exportProduct);

                //因为下面附件需要使用商品id，所以在这里现将商品id存起来
                // 添加数据：key是货物id； value是商品id
                idMap.put(contractProduct.getId(),exportProduct.getId());
            }
        }

        //4. 根据购销合同id查询所有附件，再把货物附件录入到商品附件表
        ExtCproductExample extCproductExample = new ExtCproductExample();
        extCproductExample.createCriteria().andContractIdIn(contractIdsList);
        List<ExtCproduct> extCproductList = extCproductDao.selectByExample(extCproductExample);
        if(extCproductList!=null && extCproductList.size()>0){
            //遍历购销合同附件
            for (ExtCproduct extCproduct : extCproductList) {
                //【创建商品附件】
                ExtEproduct extEproduct = new ExtEproduct();
                //【封装商品附件】
                BeanUtils.copyProperties(extCproduct,extEproduct);
                // --->1. 设置附件id
                extEproduct.setId(UUID.randomUUID().toString());
                //// --->2. 设置报运单id
                extEproduct.setExportId(export.getId());
                /**
                 * --->3. 设置报运单的商品id
                 * 已知条件： extCproduct.getContractProductId() 货物id
                 * 求解：    商品id？
                 */
                extEproduct.setExportProductId(idMap.get(extCproduct.getContractProductId()));
            }
        }
        //5. 添加报运单（商品、附件已经添加）
        export.setProNum(contractProductList.size());
        export.setExtNum(extCproductList.size());
        exportDao.insertSelective(export);
    }

    @Override
    public void update(Export export) {
        //1. 修改报运的商品
        //在报运单获取商品，报运单中含有商品类的对象
        List<ExportProduct> exportProducts = export.getExportProducts();
        if(exportProducts!=null && exportProducts.size()>0){
            //遍历商品集合
            for (ExportProduct exportProduct : exportProducts) {
                exportProductDao.updateByPrimaryKeySelective(exportProduct);
            }
        }
        exportDao.updateByPrimaryKeySelective(export);
    }

    @Override
    public void delete(String id) {
        exportDao.deleteByPrimaryKey(id);
    }

    @Override
    public PageInfo<Export> findByPage(ExportExample example, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<Export> list = exportDao.selectByExample(example);
        PageInfo<Export> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    @Override
    public void updateExport(ExportResult exportResult) {
        //海关报运的结果包含报运单，报运商品
        //先修改报运单
        Export export = new Export();
        export.setId(exportResult.getExportId());
        export.setState(exportResult.getState());
        export.setRemark(exportResult.getRemark());
        exportDao.updateByPrimaryKeySelective(export);

        //修改报运商品
        ExportProduct exportProduct = new ExportProduct();
       //获取报运单对象的全部报运商品
        Set<ExportProductResult> products = exportResult.getProducts();
        if(products!=null && products.size()>0){
            for (ExportProductResult product : products) {
                exportProduct.setId(product.getExportProductId());
                exportProduct.setTax(product.getTax());
            }
        }
        exportProductDao.updateByPrimaryKeySelective(exportProduct);

    }
}
